#include "CpuZ80.h"
#include "CpuZ80Macros.h"
#include <cassert>

byte_t CpuZ80::HandleOpcode_FDCB(byte_t operand, byte_t opcode)
{
	word_t addr = AddDisplacement(RegIY, operand);

	switch (opcode)
	{

	case 0x06: WriteByte(RotateLeftCircular(ReadByte(addr)), addr);			break; // RLC (IY+d)
	case 0x0E: WriteByte(RotateRightCircular(ReadByte(addr)), addr);		break; // RRC (IY+d)

	case 0x16: WriteByte(RotateLeft(ReadByte(addr)), addr);					break; // RL (IY+N)
	case 0x1E: WriteByte(RotateRight(ReadByte(addr)), addr);				break; // RR (IY+N)

	case 0x26: WriteByte(ShiftLeftArithmetic(ReadByte(addr)), addr);		break; // SLA (IY+N)
	case 0x2E: WriteByte(ShiftRightArithmetic(ReadByte(addr)), addr);		break; // SRA (IY+N)

	case 0x36:
	{
		byte_t data = ShiftLeftLogical(ReadByte(addr));
		data = BitSet(Bit_0, data);
		WriteByte(data, addr);
	}																		break; // SL1 (IY+N)

	case 0x3E: WriteByte(ShiftRightLogical(ReadByte(addr)), addr);			break; // SRL (IY+N)

	case 0x46: BitTest(Bit_0, ReadByte(addr));								break; // BIT 0, (IY+d)
	case 0x4E: BitTest(Bit_1, ReadByte(addr));								break; // BIT 1, (IY+d)
	case 0x56: BitTest(Bit_2, ReadByte(addr));								break; // BIT 2, (IY+d)
	case 0x5E: BitTest(Bit_3, ReadByte(addr));								break; // BIT 3, (IY+d)
	case 0x66: BitTest(Bit_4, ReadByte(addr));								break; // BIT 4, (IY+d)
	case 0x6E: BitTest(Bit_5, ReadByte(addr));								break; // BIT 5, (IY+d)
	case 0x76: BitTest(Bit_6, ReadByte(addr));								break; // BIT 6, (IY+d)
	case 0x7E: BitTest(Bit_7, ReadByte(addr));								break; // BIT 7, (IY+d)

	case 0x86: WriteByte(BitReset(Bit_0, ReadByte(addr)), addr);			break; // RES 0, (IY+d)
	case 0x8E: WriteByte(BitReset(Bit_1, ReadByte(addr)), addr);			break; // RES 1, (IY+d)
	case 0x96: WriteByte(BitReset(Bit_2, ReadByte(addr)), addr);			break; // RES 2, (IY+d)
	case 0x9E: WriteByte(BitReset(Bit_3, ReadByte(addr)), addr);			break; // RES 3, (IY+d)
	case 0xA6: WriteByte(BitReset(Bit_4, ReadByte(addr)), addr);			break; // RES 4, (IY+d)
	case 0xAE: WriteByte(BitReset(Bit_5, ReadByte(addr)), addr);			break; // RES 5, (IY+d)
	case 0xB6: WriteByte(BitReset(Bit_6, ReadByte(addr)), addr);			break; // RES 6, (IY+d)
	case 0xBE: WriteByte(BitReset(Bit_7, ReadByte(addr)), addr);			break; // RES 7, (IY+d)

	case 0xC6: WriteByte(BitSet(Bit_0, ReadByte(addr)), addr);				break; // SET 0,(IY+N)
	case 0xCE: WriteByte(BitSet(Bit_1, ReadByte(addr)), addr);				break; // SET 1,(IY+N)
	case 0xD6: WriteByte(BitSet(Bit_2, ReadByte(addr)), addr);				break; // SET 2,(IY+N)
	case 0xDE: WriteByte(BitSet(Bit_3, ReadByte(addr)), addr);				break; // SET 3,(IY+N)
	case 0xE6: WriteByte(BitSet(Bit_4, ReadByte(addr)), addr);				break; // SET 4,(IY+N)
	case 0xEE: WriteByte(BitSet(Bit_5, ReadByte(addr)), addr);				break; // SET 5,(IY+N)
	case 0xF6: WriteByte(BitSet(Bit_6, ReadByte(addr)), addr);				break; // SET 6,(IY+N)
	case 0xFE: WriteByte(BitSet(Bit_7, ReadByte(addr)), addr);				break; // SET 7,(IY+N)

	default:
		assert(false && "Unrecognized Opcode");
		break;
	}

	return m_cyclesFDCB[opcode];
}
